package cn.bby.tools.dialog;

import cn.bby.tools.dialog.common.BaseValidationDialog;
import cn.bby.tools.service.StateManagementService;
import cn.bby.tools.state.StateReference;
import cn.bby.tools.utils.ClipboardUtil;
import cn.bby.tools.utils.MessageUtil;
import cn.bby.tools.utils.SimpleEditorUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.util.ui.JBUI;
import lombok.Data;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

/**
 * 解析特殊CSV文本对话框
 * 支持识别特殊字符：x04 x02 x03 0x01作为分隔符
 *
 * @author lingma
 * @version 1.0
 */
public class ParseCsvDialog extends BaseValidationDialog implements StateReference {
    // \u0004 (EOT) - 表名和字段名的分隔符
    // \u0001 (SOH) - 字段名之间、值和值之间的分隔符
    // \u0002 (STX) - 字段名和值之间、行和行之间的分隔符
    public static final String START_FLAG = "\u0004";
    public static final String FIELD_DELIMITER = "\u0001";
    public static final String ROW_DELIMITER = "\u0002";
    private final ParseCsvState status = StateManagementService.getInstanceState().parseCsvState;
    private final String selectedText;
    private final JTextArea sourceTextArea;
    private final JTextArea resultTextArea;
    private final JRadioButton jsonRadioButton;
    private final JRadioButton csvRadioButton;
    private final ButtonGroup formatGroup;

    @Override
    public void saveState() {
        if (jsonRadioButton.isSelected()) {
            status.styleSel = "json";
        } else {
            status.styleSel = "csv";
        }
    }

    @Override
    public void loadState() {
        if (StrUtil.isEmpty(status.styleSel)) {
            status.styleSel = "csv";
        }
        if ("json".equals(status.styleSel)) {
            jsonRadioButton.setSelected(true);
        } else {
            csvRadioButton.setSelected(true);
        }
    }

    @Data
    public static class ParseCsvState {
        public String styleSel;
    }

    public ParseCsvDialog(@Nullable Project project, String selectedText) {
        super(project);
        this.selectedText = selectedText;
        this.sourceTextArea = new JTextArea(5, 100);  // 增加宽度
        this.resultTextArea = new JTextArea(15, 100); // 增加宽度
        this.jsonRadioButton = new JRadioButton(MessageUtil.getMessage("message.Json"));
        this.csvRadioButton = new JRadioButton(MessageUtil.getMessage("message.CSV"));
        this.formatGroup = new ButtonGroup();

        setTitle(MessageUtil.getMessage("action.BBY.ParseCsvAction.text"));
        init();
    }

    @Override
    protected @Nullable JComponent createCenterPanel() {
        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = JBUI.insets(5);
        gbc.anchor = GridBagConstraints.WEST;

        // 第一行：源文本显示
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 2;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weightx = 1.0;
        gbc.weighty = 0.3;
        sourceTextArea.setText(selectedText);
        sourceTextArea.setLineWrap(false); // 取消自动换行
        panel.add(new JScrollPane(sourceTextArea), gbc);

        // 第二行：格式选择单选框
        gbc.gridy = 1;
        gbc.weighty = 0;
        gbc.fill = GridBagConstraints.NONE;
        JPanel radioPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        formatGroup.add(jsonRadioButton);
        formatGroup.add(csvRadioButton);
        csvRadioButton.setSelected(true); // 默认选择CSV
        radioPanel.add(new JLabel(MessageUtil.getMessage("message.TargetFormat")));
        radioPanel.add(jsonRadioButton);
        radioPanel.add(csvRadioButton);
        panel.add(radioPanel, gbc);

        // 第三行：解析结果展示
        gbc.gridy = 2;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weighty = 0.7;
        resultTextArea.setEditable(false);
        resultTextArea.setLineWrap(false); // 取消自动换行
        panel.add(new JScrollPane(resultTextArea), gbc);

        // 添加事件监听器
        ActionListener formatListener = e -> updateResult();
        jsonRadioButton.addActionListener(formatListener);
        csvRadioButton.addActionListener(formatListener);

        loadState();
        // 初始化显示结果
        updateResult();

        return panel;
    }

    /**
     * 更新解析结果显示
     */
    private void updateResult() {
        saveState();
        try {
            // 根据特殊分隔符解析数据
            SpecialCsvData data = parseSpecialCsvData(selectedText);
            if (jsonRadioButton.isSelected()) {
                // 转换为JSON格式
                resultTextArea.setText(convertToJson(data));
            } else {
                // 转换为CSV格式
                resultTextArea.setText(convertToCsv(data));
            }
        } catch (Exception e) {
            resultTextArea.setText("解析出错: " + e.getMessage() + "\n\n原始文本:\n" + selectedText);
        }
    }

    /**
     * 解析特殊CSV数据
     *
     * @param text 原始文本
     * @return 解析后的数据结构
     */
    private SpecialCsvData parseSpecialCsvData(String text) {
        // 按照不同的分隔符拆分数据

        // ETX (End of Text)
        String endFlag = "\u0003";
        int ed = text.indexOf(endFlag);
        if (ed > 0) {
            text = text.substring(0, ed);
        }
        String tableName = "";
        int startId = text.indexOf(START_FLAG);
        if (startId >= 0) {
            tableName = text.substring(0, startId).trim();
            text = text.substring(startId + 1);
            if (tableName.indexOf(' ') > 0) {
                tableName = tableName.substring(tableName.lastIndexOf(' '));
            }
        }
        // 先按行分割(\u0002)
        String[] rows = text.split(ROW_DELIMITER);
        if (rows.length < 1) {
            return new SpecialCsvData("", new ArrayList<>(), new ArrayList<>());
        }

        // 第一行字段名

        // 字段名用\u0001分隔
        List<String> fieldNames = StrUtil.split(rows[0], FIELD_DELIMITER);

        // 解析数据行
        List<List<String>> dataRows = new ArrayList<>();
        // 从索引1开始，因为索引0是表头行
        for (int i = 1; i < rows.length; i++) {
            // 每行的数据用\u0001分隔
            dataRows.add(StrUtil.split(rows[i], FIELD_DELIMITER));
        }

        return new SpecialCsvData(tableName, fieldNames, dataRows);
    }

    /**
     * 将数据转换为JSON格式
     *
     * @param data 解析后的数据
     * @return JSON格式字符串
     */
    private String convertToJson(SpecialCsvData data) {
        JSONObject json = new JSONObject();
        json.set("tableName", data.tableName);

        JSONArray dataArray = new JSONArray();

        // 为每一行数据创建一个对象
        for (List<String> row : data.dataRows) {
            JSONObject rowObject = new JSONObject();
            // 将字段名和值配对
            for (int j = 0; j < row.size() && j < data.fieldNames.size(); j++) {
                rowObject.set(data.fieldNames.get(j), row.get(j));
            }
            dataArray.add(rowObject);
        }

        json.set("data", dataArray);
        return json.toStringPretty();
    }

    /**
     * 将数据转换为CSV格式
     *
     * @param data 解析后的数据
     * @return CSV格式字符串
     */
    private String convertToCsv(SpecialCsvData data) {
        StringBuilder csv = new StringBuilder();

        // 添加表名
        csv.append(data.tableName).append("\n");

        // 添加字段名行
        for (int i = 0; i < data.fieldNames.size(); i++) {
            csv.append(data.fieldNames.get(i));
            if (i < data.fieldNames.size() - 1) {
                csv.append(",");
            }
        }
        csv.append("\n"); // 添加末尾逗号以匹配示例格式

        // 添加数据行
        for (List<String> row : data.dataRows) {
            for (int i = 0; i < row.size(); i++) {
                csv.append(row.get(i));
                if (i < row.size() - 1) {
                    csv.append(",");
                }
            }
            csv.append("\n"); // 添加末尾逗号以匹配示例格式
        }

        return csv.toString();
    }

    @Override
    protected void doOKAction() {
        // 点击OK时关闭对话框
        close(OK_EXIT_CODE);
    }

    @Override
    protected @Nullable ValidationInfo doValidate() {
        if (StrUtil.isBlank(selectedText)) {
            return new ValidationInfo(MessageUtil.getMessage("message.TextIsEmpty"));
        }
        return super.doValidate();
    }

    @Override
    protected @NotNull Action @NotNull [] createActions() {
        // 创建自定义按钮：复制、插入、关闭
        DialogWrapperAction copyAction = new DialogWrapperAction(MessageUtil.getMessage("message.CopyAndClose")) {
            @Override
            protected void doAction(ActionEvent e) {
                ClipboardUtil.setTextToClipboard(resultTextArea.getText());
                close(OK_EXIT_CODE);
            }
        };

        DialogWrapperAction insertAction = new DialogWrapperAction(MessageUtil.getMessage("message.Insert")) {
            @Override
            protected void doAction(ActionEvent e) {
                // 获取当前项目和编辑器
                if (project != null) {
                    // 获取当前编辑器
                    boolean success = SimpleEditorUtil.replaceSelect(project, resultTextArea.getText());
                    if (success) {
                        close(OK_EXIT_CODE);
                    }
                }
            }
        };

        DialogWrapperAction closeAction = new DialogWrapperAction(MessageUtil.getMessage("message.Close")) {
            @Override
            protected void doAction(ActionEvent e) {
                doCancelAction();
            }
        };

        return new Action[]{copyAction, insertAction, closeAction};
    }

    /**
     * 特殊CSV数据结构
     */
    private static class SpecialCsvData {
        final String tableName;
        final List<String> fieldNames;
        final List<List<String>> dataRows;

        SpecialCsvData(String tableName, List<String> fieldNames, List<List<String>> dataRows) {
            this.tableName = tableName;
            this.fieldNames = fieldNames;
            this.dataRows = dataRows;
        }
    }
}